package mvc.bezier;


import java.awt.Dimension;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.media.opengl.GL;
import javax.swing.border.TitledBorder;

import org.geom.Vector3D;
import org.geom.render.Engine2D;
import org.geom.render.ViewJOGL;

public class BezierView2D extends ViewJOGL {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static boolean curvePointVisibility = true;
	public static boolean controlPointVisibility = true;
	
	protected BezierMouseController2D controller;
	protected BezierModel curveModel;
	protected String planeString;

	protected int viewport[] = new int[4];
	protected double model_view[] = new double[16];
	protected double projection[] = new double[16];
	protected double wcoord[] = new double[4];// wx, wy, wz;// returned xyz coords

	public BezierView2D(BezierModel model, String plane, Dimension d) {
		super(d);
		this.curveModel = model;
		
		this.setBorder(new TitledBorder("piano "+plane));
		
		this.planeString = plane;
	}
		
	@Override
	public void render(GL gl) {		
		//System.out.println("BezierView2D > render");
		ArrayList<Vector3D> controls = curveModel.getControlPoints();
		
		saveMatrix(gl);
			
		drawCenter(gl);
		if(curvePointVisibility)drawCurvePoints(curveModel.getPoints(), gl);
		if(controlPointVisibility)drawPoints(controls, gl);
		
		gl.glFlush();
	}

	protected void saveMatrix(GL gl) {
		//this method is needed for point selection and picking object!
		
		//System.out.println("save matrix");
		gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
		gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, model_view, 0);
		gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projection, 0);
	}

	protected void drawCenter(GL gl) {
		gl.glPushMatrix();
		gl.glScalef(10, 10, 10);

		gl.glBegin(GL.GL_LINE);

		gl.glColor3f(0, 0, 0);
		gl.glVertex3i(0, 0, 0);
		gl.glVertex3i(1, 0, 0);

		gl.glColor3f(0, 0, 0);
		gl.glVertex3i(0, 0, 0);
		gl.glVertex3i(0, 1, 0);

		gl.glEnd();

		gl.glPopMatrix();
		gl.glFlush();
	}

	protected void drawCurvePoints(ArrayList<Vector3D> points, GL gl) {
		int k = 2;

		gl.glPushMatrix();

		gl.glColor3f(0.3f,0.3f,0.3f);
		gl.glPointSize(k);
		gl.glBegin(GL.GL_POINT);
		for (Vector3D p : points) {
			
			if (this.planeString==Engine2D.X) 
				gl.glVertex2d(p.y, p.z);
			if (this.planeString==Engine2D.Y) 
				gl.glVertex2d(p.x, p.z);
			if (this.planeString==Engine2D.Z) 
				gl.glVertex2d(p.x, p.y);
		}
		gl.glEnd();
				
		gl.glPopMatrix();
		gl.glFlush();
	}
	
	protected void drawPoints(ArrayList<Vector3D> points, GL gl) {
		gl.glPushMatrix();
		
		gl.glColor3f(1.0f,1.0f,1.0f);
		gl.glBegin(GL.GL_LINE_STRIP);
		for (Vector3D p : points) {
			if (this.planeString==Engine2D.X) 
				gl.glVertex2d(p.y, p.z);
			if (this.planeString==Engine2D.Y) 
				gl.glVertex2d(p.x, p.z);
			if (this.planeString==Engine2D.Z) 
				gl.glVertex2d(p.x, p.y);
		}
		gl.glEnd();
		
		gl.glPointSize(10);
		gl.glBegin(GL.GL_POINT);
		for (Vector3D p : points) {
			if (p.equals(controller.controlPointInDrag))
				gl.glColor3f(1.0f,0.0f,0.0f);
			else gl.glColor3f(1.0f,1.0f,1.0f);
			if (this.planeString==Engine2D.X) 
				gl.glVertex3d(p.y, p.z, 0);
			if (this.planeString==Engine2D.Y) 
				gl.glVertex3d(p.x, p.z, 0);
			if (this.planeString==Engine2D.Z) 
				gl.glVertex3d(p.x, p.y, 0);
		}gl.glEnd();
		
		gl.glPopMatrix();
		gl.glFlush();
	}
	
	public void addMouseController(BezierMouseController2D controller2) {
		controller = controller2;
		addMouseListener((MouseListener) controller);
		addMouseMotionListener((MouseMotionListener) controller);
	}
	
	public String getPlaneString() {
		return planeString;
	}


}
